package com.example.springbatch3;

import com.sun.org.apache.regexp.internal.RE;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersValidator;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.job.CompositeJobParametersValidator;
import org.springframework.batch.core.job.DefaultJobParametersValidator;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@SpringBootApplication
@EnableBatchProcessing //启用springbatch框架 需要的注解
public class SpringBatchApplication3 {

    // job调度器
    @Autowired
    private JobLauncher jobLauncher;

    // job构建工厂
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    // step步骤构建工厂
    @Autowired
    private StepBuilderFactory stepBuilderFactory;


    // 任务step执行逻辑由 tasklet完成
    @StepScope //等到调用的时候再加载这个bean对象
    @Bean
    public Tasklet tasklet1() {
        return (stepContribution, chunkContext) -> {
            // 方法1，直接通过chunkContext去获取jobParameter
            Map<String, Object> jobParameters = chunkContext.getStepContext().getJobParameters();

            Object name = jobParameters.get("name");
            System.out.println("Hello Params !---" + name);

            // 方法2，通过延时加载去获取jobParameter

//            System.out.println("Hello Pamams ! ---" + name);


            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }

    // 作业步骤 不带不读写操作
    @Bean
    public Step step1() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("step1").tasklet(tasklet1()).build();
    }

    // 定制参数校验器
    @Bean
    public NameParamValidator nameParamValidator() {
        return new NameParamValidator();
    }

    /**
     * 默认参数校验器
     *
     * @return 默认参数校验器
     * 用于校验可选参数和必填参数
     */
    @Bean
    public DefaultJobParametersValidator defaultJobParametersValidator() {
        DefaultJobParametersValidator defaultJobParametersValidator = new DefaultJobParametersValidator();

        // 输入的参数必须要在RequiredKeys和OptionalKeys里面 否则会报错

        // 必须要有的参数
        defaultJobParametersValidator.setRequiredKeys(new String[]{"name"});

        // 可以选择的参数，非必填
        defaultJobParametersValidator.setOptionalKeys(new String[]{"age"});

        return defaultJobParametersValidator;

    }

    /**
     * 组合参数校验器
     * 可以传入多个校验器  只有多个校验器都执行成功才可以通过
     *
     * @return
     */
    @Bean
    public CompositeJobParametersValidator compositeJobParametersValidator() {

        CompositeJobParametersValidator compositeJobParametersValidator = new CompositeJobParametersValidator();

        compositeJobParametersValidator.setValidators(Arrays.asList(new NameParamValidator(), new DefaultJobParametersValidator()));

        return compositeJobParametersValidator;
    }


    @Bean
    public Job job() {
        return jobBuilderFactory
                .get("job-param-composite-validator")
                .validator(compositeJobParametersValidator())
                .start(step1()).
                build();
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBatchApplication3.class, args);
    }

}
